package com.gitee.wsl.ext.number

import kotlin.math.floor
import kotlin.math.log10
import kotlin.math.pow
import kotlin.math.roundToInt


fun ClosedRange<Float>.tickIncrement(count: Int) = tickIncrement(start,endInclusive,count)

@JvmName("tickIncrementDouble")
fun ClosedRange<Double>.tickIncrement(count: Int) = tickIncrement(start,endInclusive,count)


/** See equivalent [d3 function](https://github.com/d3/d3-array#tickIncrement). */
fun tickIncrement(start: Float, stop: Float, count: Int): Int =
    tickIncrement(start.toDouble(), stop.toDouble(), count)

/** See equivalent [d3 function](https://github.com/d3/d3-array#tickIncrement). */
fun tickIncrement(start: Double, stop: Double, count: Int): Int {
    require(count > 0) { "Count must be positive, but was $count." }
    if (start == stop) return 0
    require(start < stop) { "Start must be less than or equal to stop, but values were $start and $stop." }
    val step = (stop - start) / count
    val power = floor(log10(step))
    val error = step / (10.0).pow(power)
    return if (power >= 0) {
        errorScaleOf(error) * (10.0).pow(power)
    } else {
        -((10.0).pow(-power) / errorScaleOf(error))
    }.roundToInt()
}